package cn.itsource.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.itsource.constants.ErrorCode;
import cn.itsource.mapper.DriverSettingMapper;
import cn.itsource.openfeign.LoginOpenFeign;
import cn.itsource.pojo.domain.Driver;
import cn.itsource.mapper.DriverMapper;
import cn.itsource.pojo.domain.DriverSetting;
import cn.itsource.pojo.domain.DriverSettingRedisDto;
import cn.itsource.pojo.domain.Login;
import cn.itsource.pojo.dto.LocationDto;
import cn.itsource.pojo.dto.RegisterDto;
import cn.itsource.result.JSONResult;
import cn.itsource.service.IDriverService;
import cn.itsource.template.WechatTemplate;
import cn.itsource.utils.CacheConstants;
import cn.itsource.utils.IdUtil;
import cn.itsource.utils.NameUtil;
import cn.itsource.utils.RConst;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.DriverManager;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 司机对象 服务实现类
 * </p>
 *
 * @author tt
 * @since 2024-08-31
 */
@Service
public class DriverServiceImpl extends ServiceImpl<DriverMapper, Driver> implements IDriverService {

    @Autowired
    private WechatTemplate wechatTemplate;
    @Autowired
    private DriverMapper driverMapper;
    
    @Autowired
    private LoginOpenFeign loginOpenFeign;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private DriverSettingMapper driverSettingMapper;

    /**
     *司机登录
     **/
    @Override
    @Transactional
    public JSONResult registerOpenId(RegisterDto registerDto) {
        String openId = wechatTemplate.getOpenId(registerDto.getCode());
        //String phoneNumber = wechatTemplate.getPhoneNumber(registerDto.getPhoneCode());
        LambdaQueryWrapper<Driver> eq = new LambdaQueryWrapper<Driver>().eq(Driver::getOpenId,openId);
        Driver driver1 = driverMapper.selectOne(eq);
        if (driver1==null){
            Driver driver = new Driver();
            driver.setId(IdUtil.getSnowFlackId());
            //driver.setPhone(phoneNumber);
            driver.setHomeAddress("重庆市渝北区");
            driver.setHomeAddressLongitude("重庆市渝北区");
            driver.setHomeAddressLatitude("重庆市渝北区");
            driver.setCreateTime(new Date());
            driver.setPhone("16871268335");
            driver.setOpenId(openId);
            driverMapper.insert(driver);
            //将用户添加到login中
            Login login = getLogin(openId, driver);
            loginOpenFeign.create(login);
            return JSONResult.success();
        }else {
            return JSONResult.error(ErrorCode.PARAM_PHONE_EXIST);
        }

    }
    /**
     * 缓存司机位置到Redis:用geo位置缓存
     * */
    @Override
    public JSONResult online(LocationDto locationDto) {
        //保存司机的当前位置
        GeoOperations<String, Object> geo = redisTemplate.opsForGeo();
        Point point = new Point(locationDto.getLongitude(), locationDto.getLatitude());
        Long add = geo.add(CacheConstants.DRIVER_POINT_SETTING
                , point,StpUtil.getLoginIdAsLong());
        //设置过期时间
        redisTemplate.expire(CacheConstants.DRIVER_POINT_SETTING+StpUtil.getLoginIdAsLong()
                            ,RConst.Num.BASE_LONG_5, TimeUnit.MINUTES);
        //保存司机的配置
        long driverId = StpUtil.getLoginIdAsLong();
        DriverSetting driverSetting = driverSettingMapper.selectById(driverId);
        //将查询到的数据赋值给DriverSettingRedisDto
        DriverSettingRedisDto driverSettingRedisDto = new DriverSettingRedisDto();
        BeanUtils.copyProperties(driverSetting,driverSettingRedisDto);
        redisTemplate.opsForValue()
                .set(CacheConstants.DRIVER_POINT_SETTING+StpUtil.getLoginIdAsLong(),driverSettingRedisDto);
        return JSONResult.success();
    }
    /**
     * 删除Redis缓存的司机位置
     * */
    @Override
    public JSONResult offline() {
        redisTemplate.opsForGeo().remove(CacheConstants.DRIVER_POINT_SETTING
                ,StpUtil.getLoginIdAsLong());
        redisTemplate.delete(CacheConstants.DRIVER_POINT_SETTING+StpUtil.getLoginIdAsLong());
        return JSONResult.success();
    }

    /**
     * 刷新缓存司机位置到Redis:用geo位置缓存
     * */
    @Override
    public JSONResult refresh(LocationDto locationDto) {
        //保存司机的当前位置
        GeoOperations<String, Object> geo = redisTemplate.opsForGeo();
        Point point = new Point(locationDto.getLongitude(), locationDto.getLatitude());
        Long add = geo.add(CacheConstants.DRIVER_POINT_SETTING
                , point,StpUtil.getLoginIdAsLong());
        if(add==1){
            redisTemplate.expire(CacheConstants.DRIVER_POINT_SETTING+StpUtil.getLoginIdAsLong()
                                    ,RConst.Num.BASE_LONG_5,TimeUnit.MINUTES);
        }
        return JSONResult.success();
    }


    private static Login getLogin(String openId, Driver driver) {
        Login login = new Login();
        login.setId(driver.getId());
        login.setUsername(NameUtil.getName());
        login.setPassword("123456");
        login.setType(RConst.Num.INT_1);
        login.setAdmin(RConst.Num.INT_0);
        login.setNickName(login.getUsername());
        login.setOpenId(openId);
        login.setPhone(driver.getPhone());
        login.setName(login.getUsername());
        //login.setPhone(driver.getPhone());
        login.setCreateTime(new Date());
        return login;
    }
}
